﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using OS.GenericDashboardViewer.Interfaces;
using OS.GenericDashboardViewer.DataModel;
using System.Timers;
using Microsoft.Practices.Composite.Presentation.Commands;
using System.Collections.ObjectModel;

namespace OS.GenericDashboardViewer.ViewModels
{
    public class ViewPartViewModel : INotifyPropertyChanged
    {
        private const string STOP_BUTTON_CAPTION  = "Pause";
        private const  string  START_BUTTON_CAPTION = "Resume";
        private const int SEC_TO_MILLI_FACTOR = 1000;
        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged = delegate { };
        private void OnPropertyChanged(string propertyName)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion

        private int _viewPartIndex;
        private Timer _currentTimer = null;
        private IViewPartsConfiguration _partViewsConfiguration;

        public DelegateCommand<object> MoveToNext { get; set; }
        public DelegateCommand<object> MoveToPrevious { get; set; }
        public DelegateCommand<object> Stop { get; set; }

        public ObservableCollection<ViewPart> ViewParts { get; set; }

        private ViewPart _selectedViewPart;

      


        public ViewPartViewModel(IViewPartsConfiguration partViewsConfiguration)
        {
            _viewPartIndex = 0;
            PauseButton = STOP_BUTTON_CAPTION;
            _partViewsConfiguration = partViewsConfiguration;
            ViewParts = new ObservableCollection<DataModel.ViewPart>();
            partViewsConfiguration.ViewParts.ForEach(pv => ViewParts.Add(pv));
          
            InitViewPart(_partViewsConfiguration, _viewPartIndex);

            MoveToNext = new DelegateCommand<object>(obj =>  AdvenceToViewPart(_viewPartIndex + 1));
            MoveToPrevious = new DelegateCommand<object>(obj => AdvenceToViewPart(_viewPartIndex - 1));
            Stop = new DelegateCommand<object>(obj =>
            {
                if (_currentTimer != null)
                {
                    if (PauseButton == STOP_BUTTON_CAPTION)
                    {
                        _currentTimer.Stop();
                        PauseButton = START_BUTTON_CAPTION;
                    }
                    else
                    {
                        _currentTimer.Start();
                        PauseButton = STOP_BUTTON_CAPTION; ;
                    }

                }
            });
        }

        private void InitViewPart(IViewPartsConfiguration partViewsConfiguration, int viewPartIndex)
        {
            SelectedViewPart = ViewParts[viewPartIndex];
            if (_currentTimer != null)
            {
                _currentTimer.Elapsed -= OnCurrentTimer_Elapsed;
                _currentTimer.Dispose();
            }

            _currentTimer = new Timer(SelectedViewPart.DurationSeconds * SEC_TO_MILLI_FACTOR);
            _currentTimer.AutoReset = false;
            _currentTimer.Elapsed += new ElapsedEventHandler(OnCurrentTimer_Elapsed);
            _currentTimer.Start();

        }

        void OnCurrentTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            AdvenceToViewPart(_viewPartIndex + 1);
        }

        private void AdvenceToViewPart(int newIndex)
        {
            if (PauseButton == START_BUTTON_CAPTION)
            {
                PauseButton = STOP_BUTTON_CAPTION;
            }
                    
            lock (_partViewsConfiguration)
            {
                if (newIndex < 0)
                {
                    newIndex = _partViewsConfiguration.ViewParts.Count + newIndex;
                }
               
                _viewPartIndex = (newIndex) % _partViewsConfiguration.ViewParts.Count;
                InitViewPart(_partViewsConfiguration, _viewPartIndex);
            }
        }

        private string _pauseButton;

        public string PauseButton
        {
            get { return _pauseButton; }
            set
            {
                _pauseButton = value;
                OnPropertyChanged("PauseButton");
            }
        }

        public ViewPart SelectedViewPart
        {
            get { return _selectedViewPart; }
            set
            {
                if (_selectedViewPart != value && value != null)
                {
                    _selectedViewPart = value;
                    OnPropertyChanged("SelectedViewPart");
                    int newIndex = _partViewsConfiguration.ViewParts.IndexOf(_selectedViewPart);
                    if (_viewPartIndex != newIndex)
                    {
                        AdvenceToViewPart(newIndex);
                    }
                }
            }
        }
    }
}
